using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace ChatClient
{
    public partial class Form1 : Form
    {
        // Will hold the user name
        private string UserName = "Unknown";
        private StreamWriter swSender;
        private StreamReader srReceiver;
        private TcpClient tcpServer;
        // Needed to update the form with messages from another thread
        private delegate void UpdateLogCallback(string strMessage);
        // Needed to set the form to a "disconnected" state from another thread
        private delegate void CloseConnectionCallback(string strReason);
        private Thread thrMessaging;
        private IPAddress ipAddr;
        private bool Connected;

        public Form1()
        {
            // On application exit, don't forget to disconnect first
            Application.ApplicationExit += new EventHandler(OnApplicationExit);
            InitializeComponent();
        }

        // The event handler for application exit
        public void OnApplicationExit(object sender, EventArgs e)
        {
            if (Connected == true)
            {
                // Closes the connections, streams, etc.
                Connected = false;
                swSender.Close();
                srReceiver.Close();
                tcpServer.Close();
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            // If we are not currently connected but awaiting to connect
            if (Connected == false)
            {
                // Initialize the connection
                InitializeConnection();
            }
            else // We are connected, thus disconnect
            {
                CloseConnection("Disconnected at user's request.");
            }
        }

        private void InitializeConnection()
        {
            // Parse the IP address from the TextBox into an IPAddress object
            ipAddr = IPAddress.Parse(txtIp.Text);
            // Start a new TCP connections to the chat server
            tcpServer = new TcpClient();
            tcpServer.Connect(ipAddr, 1986);

            // Helps us track whether we're connected or not
            Connected = true;
            // Prepare the form
            UserName = txtUser.Text;

            // Disable and enable the appropriate fields
            txtIp.Enabled = false;
            txtUser.Enabled = false;
            txtMessage.Enabled = true;
            btnSend.Enabled = true;
            btnConnect.Text = "Disconnect";

            // Send the desired username to the server
            swSender = new StreamWriter(tcpServer.GetStream());
            swSender.WriteLine(txtUser.Text);
            swSender.Flush();

            // Start the thread for receiving messages and further communication
            thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
            thrMessaging.Start();
        }

        private void ReceiveMessages()
        {
            // Receive the response from the server
            srReceiver = new StreamReader(tcpServer.GetStream());
            // If the first character of the response is 1, connection was successful
            string ConResponse = srReceiver.ReadLine();
            // If the first character is a 1, connection was successful
            if (ConResponse[0] == '1')
            {
                // Update the form to tell it we are now connected
                this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connected Successfully!" });
            }
            else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
            {
                string Reason = "Not Connected: ";
                // Extract the reason out of the response message. The reason starts at the 3rd character
                Reason += ConResponse.Substring(2, ConResponse.Length - 2);
                // Update the form with the reason why we couldn't connect
                this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
                // Exit the method
                return;
            }
            // While we are successfully connected, read incoming lines from the server
            while (Connected)
            {
                try
                {
                    // Show the messages in the log TextBox
                    this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
                }
                catch
                {

                }

            }
        }

        // This method is called from a different thread in order to update the log TextBox
        private void UpdateLog(string strMessage)
        {
            // Append text also scrolls the TextBox to the bottom each time
            txtLog.AppendText(strMessage + "\r\n");
        }

        // Closes a current connection
        private void CloseConnection(string Reason)
        {
            // Show the reason why the connection is ending
            txtLog.AppendText(Reason + "\r\n");
            // Enable and disable the appropriate controls on the form
            txtIp.Enabled = true;
            txtUser.Enabled = true;
            txtMessage.Enabled = false;
            btnSend.Enabled = false;
            btnConnect.Text = "Connect";

            // Close the objects
            Connected = false;
            swSender.Close();
            srReceiver.Close();
            tcpServer.Close();
        }

        // Sends the message typed in to the server
        private void SendMessage()
        {
            if (txtMessage.Lines.Length >= 1)
            {
                swSender.WriteLine(txtMessage.Text);
                swSender.Flush();
                txtMessage.Lines = null;
            }
            txtMessage.Text = "";
        }

        // We want to send the message when the Send button is clicked
        private void btnSend_Click(object sender, EventArgs e)
        {
            SendMessage();
        }

        // But we also want to send the message once Enter is pressed
        private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)
        {
            // If the key is Enter
            if (e.KeyChar == (char)13)
            {
                SendMessage();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void btnCreateUser_Click(object sender, EventArgs e)
        {
            txtMessage.Text = "$SAU,CU,bill,gghttt,Bill,Smith,bill@dfg.com.au,0740553282";
            SendMessage();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            txtMessage.Text = "$SAU,LI,adam,pass";
            SendMessage();
        }

        private void btnLogout_Click(object sender, EventArgs e)
        {
            txtMessage.Text = "$SAU,LO,bill,gghttt";
            SendMessage();
        }

        private void btnAddFile_Click(object sender, EventArgs e)
        {
            txtMessage.Text = @"$SAU,AF,c:\data\big.txt";
            SendMessage();
        }

        private void btnGetProfile_Click(object sender, EventArgs e)
        {
            txtMessage.Text = @"$SAU,GP," + txtUser.Text;
            SendMessage();
        }

        private void btnGetUserList_Click(object sender, EventArgs e)
        {
            txtMessage.Text = @"$SAU,GUL," + txtUser.Text;
            SendMessage();
        }

        private void txtUser_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnFileList_Click(object sender, EventArgs e)
        {
            if (Directory.Exists(@"c:\Sauna\"+txtUser.Text))
            {
                string[] filePaths = Directory.GetFiles(@"c:\Sauna\" + txtUser.Text);
                Console.WriteLine("Found directory");
                for (int i = 0; i < filePaths.Length; i++)
                {
                    lstFiles.Items.Add(filePaths[i]);
                }

            }
        }

        private void lstFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            string f=lstFiles.SelectedItem.ToString();
            Console.WriteLine(f);
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            txtMessage.Text = "$SAU,AF,test.txt";
            SendMessage();
            frmSendFile frmSend = new frmSendFile();
            frmSend.ShowDialog();
        }

        private void btnSendTheFile_Click(object sender, EventArgs e)
        {
            //txtMessage.Text = "$SAU,AF,test.txt";
            //SendMessage();
            string s = txtFileName.Text;
            string[] strArray=s.Split('\\');

            swSender.WriteLine("$SAU,AF," + strArray[strArray.Length-1]);
            swSender.Flush();
            Stream Fs = File.OpenRead(txtFileName.Text);
            Byte[] buffer = new Byte[Fs.Length];
            Fs.Read(buffer, 0, buffer.Length);
            TcpClient socket = new TcpClient();
            socket.Connect(ipAddr, 1095);
            NetworkStream nw = socket.GetStream();
            nw.Write(buffer, 0, buffer.Length);
            nw.Close();
            //swSender.WriteLine("$SAU,AFDONE," + strArray[strArray.Length - 1]); swSender.WriteLine("$SAU,AF," + strArray[strArray.Length - 1]);
            //swSender.Flush();
            //this.Close();
            txtMessage.Text = "$SAU,AFDONE";
            SendMessage();
        }

        private void brnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofpd = new OpenFileDialog();
            ofpd.ShowDialog();
            txtFileName.Text = ofpd.FileName;
        }

        private void btnNameFile_Click(object sender, EventArgs e)
        {
            string s = txtFileName.Text;
            string[] strArray = s.Split('\\');

            swSender.WriteLine("$SAU,NF," + strArray[strArray.Length - 1]);
            swSender.Flush();
        }

        private void btnDeleteFile_Click(object sender, EventArgs e)
        {
            string s = txtFileName.Text;
            string[] strArray = s.Split('\\');

            swSender.WriteLine("$SAU,DF," + strArray[strArray.Length - 1]);
            swSender.Flush();
        }

        private void btnListFiles_Click(object sender, EventArgs e)
        {
            swSender.WriteLine("$SAU,LF,");
            swSender.Flush();
        }

        private void btnGetFile_Click(object sender, EventArgs e)
        {
            string s = txtFileName.Text;
            string[] strArray = s.Split('\\');

            swSender.WriteLine("$SAU,GF," + strArray[strArray.Length - 1]);
            swSender.Flush();
        }

        private void btnFileExists_Click(object sender, EventArgs e)
        {
            string s = txtFileName.Text;
            string[] strArray = s.Split('\\');

            swSender.WriteLine("$SAU,FE," + strArray[strArray.Length - 1]);
            swSender.Flush();
        }

        private void btnGetPassword_Click(object sender, EventArgs e)
        {
            swSender.WriteLine("$SAU,GUP," + txtUser.Text);
            swSender.Flush();
        }
        
    }
}